package com.example.layoutshotnshare;

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.User;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
import twitter4j.conf.Configuration;
import twitter4j.conf.ConfigurationBuilder;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.IntentSender.SendIntentException;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.support.v4.app.NavUtils;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockPreferenceActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.facebook.AppEventsLogger;
import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.SessionState;
import com.facebook.UiLifecycleHelper;
import com.facebook.model.GraphUser;
import com.facebook.widget.FacebookDialog;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.plus.PlusClient;

public class SettingScreen extends SherlockPreferenceActivity implements
		OnPreferenceClickListener, ConnectionCallbacks,
		OnConnectionFailedListener {

	Context context;

	public static String packageName;
	public static Twitter twitter = null;
	private static RequestToken requestToken;
	private static SharedPreferences twitterSharedPreferences;
	private AskOAuth askOAuth = null;
	private HandleTwitterOAuthCallback handleTwitterOAuthCallback = null;

	private UiLifecycleHelper uiHelper;
	private GraphUser user = null;
	private Session.StatusCallback callback = new Session.StatusCallback() {
		@Override
		public void call(Session session, SessionState state,
				Exception exception) {
			onSessionStateChange(session, state, exception);
		}
	};
	private FacebookDialog.Callback dialogCallback = new FacebookDialog.Callback() {
		@Override
		public void onError(FacebookDialog.PendingCall pendingCall,
				Exception error, Bundle data) {
			Log.d("Nam Dinh", String.format("Error: %s", error.toString()));
		}

		@Override
		public void onComplete(FacebookDialog.PendingCall pendingCall,
				Bundle data) {
			Log.d("Nam Dinh", "Success!");
		}
	};

	private static final int REQUEST_CODE_RESOLVE_ERR = 9000;
	private static final String PLUS_WRITE_MOMENT = " https://www.googleapis.com/auth/plus.moments.write";
	static final String[] SCOPES = { Scopes.PLUS_PROFILE, PLUS_WRITE_MOMENT };
	private ProgressDialog mConnectionProgressDialog;
	private PlusClient mPlusClient;
	private ConnectionResult mConnectionResult;

	private ConnectionDetector cd;

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);

		// Action bar: add Back button
		getSupportActionBar().setDisplayHomeAsUpEnabled(true);

		return true;
	}

	@SuppressWarnings("deprecation")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		context = this;
		addPreferencesFromResource(R.xml.settings);
		packageName = getApplicationContext().getPackageName();
		
		cd = new ConnectionDetector(getApplicationContext());

		// try {
		// PackageInfo info = getPackageManager().getPackageInfo(
		// "com.example.layoutshotnshare",
		// PackageManager.GET_SIGNATURES);
		// for (Signature signature : info.signatures) {
		// MessageDigest md = MessageDigest.getInstance("SHA");
		// md.update(signature.toByteArray());
		// Log.d("KeyHash:",
		// Base64.encodeToString(md.digest(), Base64.DEFAULT));
		// }
		// } catch (NameNotFoundException e) {
		//
		// } catch (NoSuchAlgorithmException e) {
		//
		// }

		findPreference("pref_feedback").setOnPreferenceClickListener(this);
		findPreference("pref_rating").setOnPreferenceClickListener(this);
		findPreference("pref_twitter").setOnPreferenceClickListener(this);
		findPreference("pref_facebook").setOnPreferenceClickListener(this);
		findPreference("pref_google").setOnPreferenceClickListener(this);

		/**
		 * Facebook
		 */

		uiHelper = new UiLifecycleHelper(this, callback);
		uiHelper.onCreate(savedInstanceState);

		/**
		 * Twitter
		 */
		twitterSharedPreferences = getSharedPreferences(
				TwitterConst.PREFERENCE_NAME, MODE_PRIVATE);

		Uri uri = getIntent().getData();
		if (uri != null && uri.toString().startsWith(TwitterConst.CALLBACK_URL)) {

			String verifier = uri
					.getQueryParameter(TwitterConst.IEXTRA_OAUTH_VERIFIER);
			String[] params = new String[] { verifier };
			handleTwitterOAuthCallback = new HandleTwitterOAuthCallback();
			handleTwitterOAuthCallback.execute(params);
		}

		/**
		 * Google plus
		 */
		mPlusClient = new PlusClient.Builder(this, this, this)
				.setVisibleActivities("http://schemas.google.com/AddActivity",
						"http://schemas.google.com/BuyActivity")
				.setScopes(SCOPES) // Space separated list of scopes
				.build();
		// Progress bar to be displayed if the connection failure is not
		// resolved.
		mConnectionProgressDialog = new ProgressDialog(this);
		mConnectionProgressDialog.setMessage("Signing in...");

	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		// -------Login Facebook--------//
		if (Session.getActiveSession() != null) {
			Session.getActiveSession().onActivityResult(this, requestCode,
					resultCode, data);
		}
		uiHelper.onActivityResult(requestCode, resultCode, data, dialogCallback);

		if (requestCode == REQUEST_CODE_RESOLVE_ERR && resultCode == RESULT_OK) {
			mConnectionResult = null;
			mPlusClient.connect();
		}
	}

	@SuppressWarnings("deprecation")
	protected void onResume() {
		super.onResume();
		/**
		 * Facebook
		 */
		uiHelper.onResume();
		AppEventsLogger.activateApp(this);
		updateFacebookUI();

		/**
		 * Twitter
		 */
		if (isConnectedTwitter()) {
			if (twitter != null) {
				String account = twitterSharedPreferences.getString(
						TwitterConst.PREF_KEY_ACCOUNT, "");

				findPreference("pref_twitter")
						.setSummary("Account: " + account);

			} else {
				findPreference("pref_twitter").setSummary("Not set");
				disconnectTwitter();
			}

		} else {
			findPreference("pref_twitter").setSummary("Not set");
		}

		/**
		 * Google Plus
		 */

		if (mPlusClient.isConnected()) {
			findPreference("pref_google").setSummary(
					"Account: " + mPlusClient.getAccountName());
		}
	}

	@Override
	protected void onStart() {
		super.onStart();
		mPlusClient.connect();
	}

	@Override
	public void onPause() {
		super.onPause();
		uiHelper.onPause();
	}

	@Override
	protected void onStop() {
		super.onStop();
		mPlusClient.disconnect();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		uiHelper.onDestroy();
		if (askOAuth != null) {
			askOAuth.cancel(true);
		}
		if (handleTwitterOAuthCallback != null) {
			handleTwitterOAuthCallback.cancel(true);
		}
	}

	private void onSessionStateChange(Session session, SessionState state,
			Exception exception) {
		updateFacebookUI();
	}

	@SuppressWarnings("deprecation")
	private void updateFacebookUI() {
		Session session = Session.getActiveSession();
		boolean enableButtons = (session != null && session.isOpened());

		if (enableButtons) {
			// make request to the /me API
			Request.executeMeRequestAsync(session,
					new Request.GraphUserCallback() {
						// callback after Graph API response with user object
						@Override
						public void onCompleted(GraphUser user,
								Response response) {
							if (user != null) {
								SettingScreen.this.user = user;
								findPreference("pref_facebook").setSummary(
										"Account: " + user.getName());
							} else {
								findPreference("pref_facebook").setSummary(
										"Not set");
							}
						}
					});
		} else {
			findPreference("pref_facebook").setSummary("Not set");
		}
	}

	private boolean isConnectedTwitter() {
		return twitterSharedPreferences.getString(TwitterConst.PREF_KEY_TOKEN,
				null) != null;
	}

	private class HandleTwitterOAuthCallback extends
			AsyncTask<String, Void, String> {

		@Override
		protected String doInBackground(String... params) {

			try {
				AccessToken accessToken = twitter.getOAuthAccessToken(
						requestToken, params[0]);
				long userID = accessToken.getUserId();
				User user = twitter.showUser(userID);

				Editor e = twitterSharedPreferences.edit();
				e.putString(TwitterConst.PREF_KEY_TOKEN, accessToken.getToken());
				e.putString(TwitterConst.PREF_KEY_SECRET,
						accessToken.getTokenSecret());
				e.putString(TwitterConst.PREF_KEY_ACCOUNT, user.getName());

				e.commit();
			} catch (Exception e) {

			}
			return "Executed";
		}

		@SuppressWarnings("deprecation")
		@Override
		protected void onPostExecute(String result) {
			if (isConnectedTwitter()) {
				if (twitter != null) {
					String account = twitterSharedPreferences.getString(
							TwitterConst.PREF_KEY_ACCOUNT, "");

					findPreference("pref_twitter").setSummary(
							"Account: " + account);

				} else {
					findPreference("pref_twitter").setSummary("Not set");
					disconnectTwitter();
				}

			} else {
				findPreference("pref_twitter").setSummary("Not set");
			}
		}
	}

	private class AskOAuth extends AsyncTask<String, Void, String> {

		@Override
		protected String doInBackground(String... params) {
			ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
			configurationBuilder.setOAuthConsumerKey(TwitterConst.CONSUMER_KEY);
			configurationBuilder
					.setOAuthConsumerSecret(TwitterConst.CONSUMER_SECRET);
			Configuration configuration = configurationBuilder.build();
			twitter = new TwitterFactory(configuration).getInstance();

			try {
				requestToken = twitter
						.getOAuthRequestToken(TwitterConst.CALLBACK_URL);

				startActivity(new Intent(Intent.ACTION_VIEW,
						Uri.parse(requestToken.getAuthenticationURL())));
			} catch (TwitterException e) {
				e.printStackTrace();
			}
			return "Executed";
		}

		@Override
		protected void onPostExecute(String result) {

		}
	}

	/**
	 * Remove Token, Secret from preferences
	 */
	private void disconnectTwitter() {
		SharedPreferences.Editor editor = twitterSharedPreferences.edit();
		editor.remove(TwitterConst.PREF_KEY_TOKEN);
		editor.remove(TwitterConst.PREF_KEY_SECRET);
		editor.commit();
	}

	public void showAlertDialog(Context context, String title, String message) {
		AlertDialog alertDialog = new AlertDialog.Builder(context).create();

		// Setting Dialog Title
		alertDialog.setTitle(title);

		// Setting Dialog Message
		alertDialog.setMessage(message);

		// Setting alert dialog icon
		alertDialog.setIcon(R.drawable.fail);

		// Setting OK Button
		alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
			}
		});

		// Showing Alert Message
		alertDialog.show();
	}

	@Override
	public boolean onPreferenceClick(Preference preference) {
		String key = preference.getKey();
		if (key.equals("pref_feedback")) {
			final Dialog dialog = new Dialog(context);
			dialog.setContentView(R.layout.dialog_feedback);
			dialog.setTitle("Send feedback");

			final Button dialogSend = (Button) dialog
					.findViewById(R.id.btt_fbsend);
			dialogSend.setEnabled(false);

			Button dialogCancel = (Button) dialog
					.findViewById(R.id.btt_fbcancel);

			final EditText textMessage = (EditText) dialog
					.findViewById(R.id.tb_message);
			textMessage.addTextChangedListener(new TextWatcher() {

				@Override
				public void onTextChanged(CharSequence arg0, int arg1,
						int arg2, int arg3) {

				}

				@Override
				public void beforeTextChanged(CharSequence arg0, int arg1,
						int arg2, int arg3) {

				}

				@Override
				public void afterTextChanged(Editable arg0) {

					if (textMessage.getText().toString().equals("")) {
						dialogSend.setEnabled(false);
					} else
						dialogSend.setEnabled(true);
				}
			});

			dialogCancel.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View arg0) {
					dialog.dismiss();
				}
			});

			dialogSend.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View v) {
					// Send Mail
					String supportMail[] = { "shotnshareapp@gmail.com" };

					Intent email = new Intent(Intent.ACTION_SEND);
					email.putExtra(android.content.Intent.EXTRA_EMAIL,
							supportMail);
					email.putExtra(android.content.Intent.EXTRA_SUBJECT,
							"[Send feedback]");
					email.setType("plain/text");
					email.putExtra(android.content.Intent.EXTRA_TEXT,
							textMessage.getText().toString());
					startActivity(email);
				}
			});
			dialog.show();
			return true;
		} else if (key.equals("pref_rating")) {

			Intent intent = new Intent(Intent.ACTION_VIEW);
			// Try Google play
			intent.setData(Uri
					.parse("market://details?id=" + packageName));
			if (MyStartActivity(intent) == false) {
				// Market (Google play) app seems not installed, let's try to
				// open a webbrowser
				intent.setData(Uri
						.parse("https://play.google.com/store/apps/details?id=" + packageName));
				if (MyStartActivity(intent) == false) {
					// Well if this also fails, we have run out of options,
					// inform the user.
					Toast.makeText(
							this,
							"Could not open Android market, please install the market app.",
							Toast.LENGTH_SHORT).show();
				}
			}

			// Intent intent = new Intent(getApplicationContext(),
			// ShareScreen.class);
			// startActivity(intent);

			return true;
		} else if (key.equals("pref_twitter")) {
			if (isConnectedTwitter()) {
				if (twitter != null) {
					String account = twitterSharedPreferences.getString(
							TwitterConst.PREF_KEY_ACCOUNT, "");

					AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
							SettingScreen.this);
					// set title
					alertDialogBuilder.setTitle("Twitter Information");
					// set dialog message
					alertDialogBuilder
							.setMessage(
									"You are logged in as " + account
											+ ". Do you want to logout?")
							.setCancelable(false)
							.setPositiveButton("Yes",
									new DialogInterface.OnClickListener() {
										public void onClick(
												DialogInterface dialog, int id) {
											disconnectTwitter();
											findPreference("pref_twitter")
													.setSummary("Not set");
											dialog.cancel();
										}
									})
							.setNegativeButton("No",
									new DialogInterface.OnClickListener() {

										@Override
										public void onClick(
												DialogInterface dialog,
												int which) {

											dialog.cancel();
										}

									});

					alertDialogBuilder.setCancelable(false);
					alertDialogBuilder.show();
				} else {
					if (!cd.isConnectingToInternet()) {
						showAlertDialog(SettingScreen.this,
								"No Internet Connection",
								"To login Twitter you need to be connected to the Internet.");

					} else {
						askOAuth = new AskOAuth();
						askOAuth.execute();
					}

				}

			} else {
				if (!cd.isConnectingToInternet()) {
					showAlertDialog(SettingScreen.this,
							"No Internet Connection",
							"To login Twitter you need to be connected to the Internet.");

				} else {
					askOAuth = new AskOAuth();
					askOAuth.execute();
				}
			}
			return true;
		} else if (key.equals("pref_facebook")) {

			Session session = Session.getActiveSession();
			boolean enableButtons = (session != null && session.isOpened());
			if (enableButtons) {
				if (SettingScreen.this.user != null) {
					AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
							SettingScreen.this);
					// set title
					alertDialogBuilder.setTitle("Facebook Information");
					// set dialog message
					alertDialogBuilder
							.setMessage(
									"You are logged in as " + user.getName()
											+ ". Do you want to logout?")
							.setCancelable(false)
							.setPositiveButton("Yes",
									new DialogInterface.OnClickListener() {
										public void onClick(
												DialogInterface dialog, int id) {
											// TODO
											Session session = Session
													.getActiveSession();
											session.closeAndClearTokenInformation();
											findPreference("pref_facebook")
													.setSummary("Not set");
											dialog.cancel();
										}
									})
							.setNegativeButton("No",
									new DialogInterface.OnClickListener() {

										@Override
										public void onClick(
												DialogInterface dialog,
												int which) {

											dialog.cancel();
										}

									});

					alertDialogBuilder.setCancelable(false);
					alertDialogBuilder.show();
				} else {
					if (!cd.isConnectingToInternet()) {
						showAlertDialog(SettingScreen.this,
								"No Internet Connection",
								"To login Facebook you need to be connected to the Internet.");

					} else {
						// start Facebook Login
						Session.openActiveSession(this, true,
								new Session.StatusCallback() {
									// callback when session changes state
									@SuppressWarnings("deprecation")
									@Override
									public void call(Session session,
											SessionState state,
											Exception exception) {
										if (session.isOpened()) {
											// make request to the /me API
											Request.executeMeRequestAsync(
													session,
													new Request.GraphUserCallback() {

														// callback after Graph
														// API
														// response with user
														// object
														@Override
														public void onCompleted(
																GraphUser user,
																Response response) {
															if (user != null) {
																SettingScreen.this.user = user;
																findPreference(
																		"pref_facebook")
																		.setSummary(
																				"Account: "
																						+ user.getName());
															}
														}
													});
										}
									}
								});
					}

				}

			} else {
				if (!cd.isConnectingToInternet()) {
					showAlertDialog(SettingScreen.this,
							"No Internet Connection",
							"To login Facebook you need to be connected to the Internet.");

				} else {
					// start Facebook Login
					Session.openActiveSession(this, true,
							new Session.StatusCallback() {
								// callback when session changes state
								@SuppressWarnings("deprecation")
								@Override
								public void call(Session session,
										SessionState state, Exception exception) {
									if (session.isOpened()) {
										// make request to the /me API
										Request.executeMeRequestAsync(
												session,
												new Request.GraphUserCallback() {
													// callback after Graph API
													// response with user object
													@Override
													public void onCompleted(
															GraphUser user,
															Response response) {
														if (user != null) {
															SettingScreen.this.user = user;
															findPreference(
																	"pref_facebook")
																	.setSummary(
																			"Account: "
																					+ user.getName());
														}
													}
												});
									}
								}
							});
				}

			}

			return true;
		} else if (key.equals("pref_google")) {

			int errorCode = GooglePlayServicesUtil
					.isGooglePlayServicesAvailable(getApplicationContext());
			if (errorCode != ConnectionResult.SUCCESS) {
				GooglePlayServicesUtil.getErrorDialog(errorCode, this, 0)
						.show();
			} else {
				if (!mPlusClient.isConnected()) {
					if (!cd.isConnectingToInternet()) {
						showAlertDialog(SettingScreen.this,
								"No Internet Connection",
								"To login Google Plus you need to be connected to the Internet.");

					} else {
						if (mConnectionResult == null) {
							mConnectionProgressDialog.show();
						} else {
							try {
								mConnectionResult.startResolutionForResult(
										this, REQUEST_CODE_RESOLVE_ERR);
							} catch (SendIntentException e) {
								// Try connecting again.
								mConnectionResult = null;
								mPlusClient.connect();
							}
						}
					}

				} else if (mPlusClient.isConnected()) {

					AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
							SettingScreen.this);
					// set title
					alertDialogBuilder.setTitle("Google Plus Information");
					// set dialog message
					alertDialogBuilder
							.setMessage(
									"You are logged in as "
											+ mPlusClient.getAccountName()
											+ ". Do you want to logout?")
							.setCancelable(false)
							.setPositiveButton("Yes",
									new DialogInterface.OnClickListener() {
										public void onClick(
												DialogInterface dialog, int id) {
											mPlusClient.clearDefaultAccount();
											mPlusClient.disconnect();
											mPlusClient.connect();
											findPreference("pref_google")
													.setSummary("Not set");
											dialog.cancel();
										}
									})
							.setNegativeButton("No",
									new DialogInterface.OnClickListener() {

										@Override
										public void onClick(
												DialogInterface dialog,
												int which) {

											dialog.cancel();
										}

									});

					alertDialogBuilder.setCancelable(false);
					alertDialogBuilder.show();

				}
			}

			return true;
		}
		return false;
	}

	private boolean MyStartActivity(Intent aIntent) {
		try {
			startActivity(aIntent);
			return true;
		} catch (ActivityNotFoundException e) {
			return false;
		}
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home: // up to 1st screen: Camera
			Bundle extras = getIntent().getExtras();

			if (extras.getInt("from_screen") == 4) {
				Intent returnIntent = new Intent(this, ShareScreen.class);
				setResult(RESULT_CANCELED, returnIntent);
				finish();
			} else {
				NavUtils.navigateUpTo(this, new Intent(this,
						New_FirstScreen.class));

			}
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			Bundle extras = getIntent().getExtras();

			if (extras.getInt("from_screen") == 4) {
				Intent returnIntent = new Intent(this, ShareScreen.class);
				setResult(RESULT_CANCELED, returnIntent);
				finish();
			} else {
				NavUtils.navigateUpTo(this, new Intent(this,
						New_FirstScreen.class));

			}
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public void onConnectionFailed(ConnectionResult result) {
		if (mConnectionProgressDialog.isShowing()) {
			// The user clicked the sign-in button already. Start to resolve
			// connection errors. Wait until onConnected() to dismiss the
			// connection dialog.
			if (result.hasResolution()) {
				try {
					result.startResolutionForResult(this,
							REQUEST_CODE_RESOLVE_ERR);
				} catch (SendIntentException e) {
					mPlusClient.connect();
				}
			}
		}
		// Save the intent so that we can start an activity when the user clicks
		// the sign-in button.
		mConnectionResult = result;
	}

	@Override
	public void onConnected(Bundle connectionHint) {
		// We've resolved any connection errors.
		mConnectionProgressDialog.dismiss();
		findPreference("pref_google").setSummary(
				"Account: " + mPlusClient.getAccountName());
	}

	@Override
	public void onDisconnected() {
		Log.d("Nam Dinh", "disconnected");
	}

}
